#include <QtGui/QApplication>
#include <QDesktopWidget>
#include <QTextCodec>
#include "widget/mainWindow/mainwindow.h"
#include "widget/splashScreen/splashscreen.h"
#include "widget/LoginDialog/logindialog.h"
#include "tools/threadhand.h"
#include "dev/serialPort/serialport.h"
#include "algorithm/nodetopology.h"
#include "control/gsm/gsmcontrol.h"
#include "tools/constant.h"
#include "database/database.h"
#include "model/node.h"
#include "control/zigbee/zigbeedatacontrol.h"
#include "widget/InputPanel/myinputpanelcontext.h"
#include "simulator/simulator.h"
#include "simulator/zigbeeserialportcontrolsimulator.h"



#define SIMULATOR






bool getParameters(const QString &fileName) {
    QFile file(fileName);
    if (file.open(QIODevice::ReadOnly)) {
        QTextStream out(&file);
        Parameters::cmsaddr = QObject::trUtf8("+861380%1").arg(out.readLine().trimmed()).trimmed() + "500";
        Parameters::phone = QObject::trUtf8("+86%1").arg(out.readLine().trimmed()).trimmed();
        //        bool ok = false;
        Parameters::interval_time = out.readLine().trimmed().toInt();
        //        if (ok) {
        //            ok = false;
        //            Parameters::interval_time = t1;
        //        }
        Parameters::interval = out.readLine().trimmed().toInt();
        Parameters::TestDuration = out.readLine().trimmed().toInt();
        Parameters::boundaryValue = out.readLine().trimmed().toInt();
        Parameters::spaceTime = out.readLine().trimmed().toInt();;
        return true;
    }
    return false;
}

void setAppStyle(QApplication &app,const QString &style_name)
{
    QFile file(QString("css/%1.css").arg(style_name));
    do {

        if (!file.open(QFile::ReadOnly)) {
            qDebug() << "Open CSS file error!" << file.errorString();
            break;
        }
        QString qss = QLatin1String(file.readAll());
        app.setStyleSheet(qss);

    }while(0);




}


int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    /**
     * @brief ic 输入法
     */
    MyInputPanelContext *ic = new MyInputPanelContext;
    app.setInputContext(ic);

    setAppStyle(app,"navy");

    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));


    //处理中文编码
    QTextCodec *code = QTextCodec::codecForName("utf-8");
    QTextCodec::setCodecForLocale(code);

    //注册这些类，使其支持signal and slot
    qRegisterMetaType<SerialPortData>("SerialPortData");
    qRegisterMetaType<Node>("Node");
    qRegisterMetaType<Message>("Message");

    //连接到数据库
    if (!DBcontrol::createConnection("Data.db")) {
        return -1;
    }

    if (getParameters("conf/Parameters.conf")) {
        qDebug() << "ok" << Parameters::cmsaddr << Parameters::phone
                 << Parameters::interval_time << Parameters::interval
                 <<Parameters::TestDuration << Parameters::boundaryValue
                <<Parameters::spaceTime;
    } else {
        qDebug() << "Parameters load error!\n";
        return -1;
    }



#ifndef SIMULATOR
    //zigbee协调器串口读写线程
    ThreadHand hand1(new QThread());
    SerialPort ZigBeeSerialPort;
    hand1.ObjMoveIn(&ZigBeeSerialPort);
#else
    ZigBeeSerialPortControlSimulator ZSPCSimulator;
#endif

    //节点管理线程
    ThreadHand hand2(new QThread());
    NodeTopology nodet(0,1000*Parameters::TestDuration,Parameters::boundaryValue,1000*Parameters::spaceTime);
    hand2.ObjMoveIn(&nodet);

    //gsm串口读写进程
    ThreadHand hand3(new QThread());
    SerialPort gsmport;
    gsmport.changeWorkMode(GSM);
    hand3.ObjMoveIn(&gsmport);

#ifndef SIMULATOR
    //控制中间层
    ZigBeeDataControl zigbeeC;
#else
    //数据模拟
    Simulator simulator;
#endif
    GSMcontrol gsmC;









    QPixmap pix(":/picture/rain_meitu_1.jpg");
    SplashScreen *ps = new SplashScreen(pix);
    ps->setShowSecond(1);
    ps->startTimer();
    LoginDialog *ld = new LoginDialog;
    QObject::connect(ps,SIGNAL(timeOver()),ld,SLOT(show()));
    MainWindow w;

    QObject::connect(ld,SIGNAL(passwordRight()),&w,SLOT(showWindow()));

    QObject::connect(ld,SIGNAL(quitSystem()),qApp,SLOT(quit()));

#ifndef SIMULATOR
    QObject::connect(&w,SIGNAL(sig_activatedZIgBee(QString)),
                     &ZigBeeSerialPort,SLOT(slt_SerialPortInfo(QString)));
    QObject::connect(&w,SIGNAL(sig_setZigBeeWorkStatus(QString,bool)),
                     &ZigBeeSerialPort,SLOT(slt_setDevOnOrOff(QString,bool)));
    QObject::connect(&ZigBeeSerialPort,SIGNAL(sig_SerialPortInfo(QString,bool)),
                     &w,SLOT(slt_getZigBeeInfo(QString,bool)));
    QObject::connect(&ZigBeeSerialPort,SIGNAL(sig_close()),&nodet,SLOT(slt_stopTest()));
    QObject::connect(&nodet,SIGNAL(sig_TestNode(QByteArray)),
                     &ZigBeeSerialPort,SLOT(slt_writeSerialPort(QByteArray)));
    /////
    /// \brief　zigbee协调器串口数据发送到数据控制控制层
    ///
    QObject::connect(&ZigBeeSerialPort,SIGNAL(sig_SerialPortDataComed(SerialPortData)),
                     &zigbeeC,SLOT(slt_data(SerialPortData)));
    QObject::connect(&nodet,SIGNAL(sig_TestNode(QByteArray)),
                     &ZigBeeSerialPort,SLOT(slt_writeSerialPort(QByteArray)));
    QObject::connect(&ZigBeeSerialPort,SIGNAL(sig_realTimeInfo(QString)),
                     &w,SLOT(slt_printInfo(QString)));

#else
    QObject::connect(&w, SIGNAL(sig_activatedZIgBee(QString)),
                     &ZSPCSimulator, SLOT(slt_SerialPortInfo(QString)));
    QObject::connect(&w, SIGNAL(sig_setZigBeeWorkStatus(QString,bool)),
                     &ZSPCSimulator, SLOT(slt_setDevOnOrOff(QString,bool)));
    QObject::connect(&ZSPCSimulator, SIGNAL(sig_SerialPortInfo(QString,bool)),
                     &w, SLOT(slt_getZigBeeInfo(QString,bool)));
    QObject::connect(&ZSPCSimulator, SIGNAL(sig_open()),
                     &simulator, SLOT(SltStart()));
    QObject::connect(&ZSPCSimulator, SIGNAL(sig_close()),
                     &simulator, SLOT(SltStop()));
    QObject::connect(&ZSPCSimulator, SIGNAL(sig_close()),
                     &nodet, SLOT(slt_stopTest()));

#endif
    QObject::connect(&w,SIGNAL(sig_setGSMworkStatus(QString,bool)),
                     &gsmport,SLOT(slt_setDevOnOrOff(QString,bool)));




    QObject::connect(&nodet,SIGNAL(sig_newNode(Node)),&w,SLOT(slt_newNode(Node)));
    QObject::connect(&nodet,SIGNAL(sig_nodeChange(Node)),&w,SLOT(slt_ChangNodeState(Node)));





#ifndef SIMULATOR
    QObject::connect(&zigbeeC,SIGNAL(sig_clear0(ushort)),&nodet,SLOT(slt_nodeClear0(ushort)));
    QObject::connect(&zigbeeC,SIGNAL(sig_badData(ushort,int,int)),
                     &nodet,SLOT(slt_badData(ushort,int,int)));
    QObject::connect(&zigbeeC,SIGNAL(sig_netTopologyBuild(char,QString,QString,ushort)),
                     &nodet,SLOT(slt_buildNet(char,QString,QString,ushort)));
    QObject::connect(&zigbeeC,SIGNAL(sig_netTopologyTest(QString,ushort)),
                     &nodet,SLOT(slt_NodeTest(QString,ushort)));
    QObject::connect(&zigbeeC,SIGNAL(sig_items(QString,int,int,int)),
                     &w,SLOT(slt_setListItems(QString,int,int,int)));


    QObject::connect(&zigbeeC,SIGNAL(sig_sensorData(ushort,int,int)),
                     &w,SLOT(slt_sensorData(ushort,int,int)));

    QObject::connect(&w,SIGNAL(sig_aFilter(Filter)),&zigbeeC,SLOT(slt_addAfilte(Filter)));


    QObject::connect(&zigbeeC,SIGNAL(sig_realTimeInfo(QString)),&w,SLOT(slt_printInfo(QString)));
#else
    QObject::connect(&simulator, SIGNAL(sig_clear0(ushort)),
                     &nodet, SLOT(slt_nodeClear0(ushort)));
    QObject::connect(&simulator, SIGNAL(sig_badData(ushort,int,int)),
                     &nodet, SLOT(slt_badData(ushort,int,int)));
    QObject::connect(&simulator, SIGNAL(sig_netTopologyBuild(char,QString,QString,ushort)),
                     &nodet, SLOT(slt_buildNet(char,QString,QString,ushort)));
    QObject::connect(&simulator, SIGNAL(sig_netTopologyTest(QString,ushort)),
                     &nodet, SLOT(slt_NodeTest(QString,ushort)));
    QObject::connect(&simulator, SIGNAL(sig_items(QString,int,int,int)),
                     &w, SLOT(slt_setListItems(QString,int,int,int)));
    QObject::connect(&simulator, SIGNAL(sig_sensorData(ushort,int,int)),
                     &w, SLOT(slt_sensorData(ushort,int,int)));
    QObject::connect(&w, SIGNAL(sig_aFilter(Filter)),
                     &simulator, SLOT(slt_addAfilte(Filter)));
    QObject::connect(&simulator, SIGNAL(sig_realTimeInfo(QString)),
                     &w, SLOT(slt_printInfo(QString)));

#endif
    QObject::connect(&nodet,SIGNAL(sig_realTimeInfo(QString)),&w,SLOT(slt_printInfo(QString)));

    QObject::connect(&gsmC,SIGNAL(sig_realTimeInfo(QString)),&w,SLOT(slt_printInfo(QString)));
    QObject::connect(&gsmC,SIGNAL(sig_error()),&gsmport,SLOT(slt_close()));
    QObject::connect(&gsmport,SIGNAL(sig_realTimeInfo(QString)),&w,SLOT(slt_printInfo(QString)));

    QObject::connect(&gsmport,SIGNAL(sig_GSMCMDok(int)),&gsmC,SLOT(slt_SendMessage(int)));


    QObject::connect(&gsmC,SIGNAL(sig_CMGS(int)),&gsmport,SLOT(slt_AT_CMGS(int)));
    QObject::connect(&gsmC,SIGNAL(sig_wirtePDU(QByteArray)),&gsmport,SLOT(slt_AT_Content(QByteArray)));

    QObject::connect(&gsmC,SIGNAL(sig_CMGF()),&gsmport,SLOT(slt_AT_CMGF()));

    QObject::connect(&gsmport,SIGNAL(sig_SerialPortInfo(QString,bool)),&w,SLOT(slt_getGSMinfo(QString,bool)));

    QObject::connect(&nodet,SIGNAL(sig_Message(Message)),&gsmC,SLOT(slt_getMessage(Message)));
    QObject::connect(&w,SIGNAL(sig_sendMessage(Message)),&gsmC,SLOT(slt_getMessage(Message)));


    QDesktopWidget *dw = QApplication::desktop();
#ifdef SIMULATOR
    w.resize(dw->size() * 0.85);//以设备的显示器件的大小来确定主界面的大小
    w.move((dw->width() - w.width()) / 2, (dw->height() - w.height()) / 2);
#else
    w.resize(dw->size());//以设备的显示器件的大小来确定主界面的大小
#endif

#ifndef SIMULATOR
    hand1.start();
#endif
    hand2.start();
    hand3.start();

    return app.exec();
}
